package com.ruoyi.app.business.account;

import com.ruoyi.app.config.platform.PlatFormConfig;
import com.ruoyi.app.config.util.UserUtil;
import com.ruoyi.common.core.enums.IOFlagEnum;
import com.ruoyi.common.core.utils.CommonUtils;
import com.ruoyi.service.account.entity.PlatformAccountDetailEntity;
import com.ruoyi.service.account.entity.PlatformAccountEntity;
import com.ruoyi.service.account.enums.platform.PlatformChangeTypeEnum;
import com.ruoyi.service.account.service.PlatformAccountDetailService;
import com.ruoyi.service.account.service.PlatformAccountService;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Optional;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 作用：平台账户管理
 * </p>
 *
 * @author Zane
 * @since 2025-10-19 9:08
 */
@Component
public class PlatformAccountBusiness {

  @Resource
  private PlatformAccountService platformAccountService;
  @Resource
  private PlatformAccountDetailService platformAccountDetailService;
  @Resource
  private PlatFormConfig platFormConfig;


  @Transactional(rollbackFor = Exception.class)
  public void change(BigDecimal changeAmount, PlatformChangeTypeEnum changeTypeEnum,
      String changeComment, Long traceId) {
    this.changeWithCommissionAmount(changeAmount, BigDecimal.ZERO, changeTypeEnum, changeComment,
        String.valueOf(traceId));
  }

  @Transactional(rollbackFor = Exception.class)
  public void change(BigDecimal changeAmount,
      PlatformChangeTypeEnum changeTypeEnum,
      String changeComment, String traceId) {
    this.changeWithCommissionAmount(changeAmount, BigDecimal.ZERO, changeTypeEnum, changeComment,
        traceId);
  }

  @Transactional(rollbackFor = Exception.class)
  public void changeWithCommissionAmount(BigDecimal changeAmount, BigDecimal commissionAmount,
      PlatformChangeTypeEnum changeTypeEnum, String changeComment, Long traceId) {
    this.changeWithCommissionAmount(changeAmount, commissionAmount, changeTypeEnum, changeComment,
        String.valueOf(traceId));
  }

  @Transactional(rollbackFor = Exception.class)
  public void changeWithCommissionAmount(BigDecimal changeAmount, BigDecimal commissionAmount,
      PlatformChangeTypeEnum changeTypeEnum, String changeComment, String traceId) {
    final PlatformAccountDetailEntity accountDetailEntity = initAccountDetailEntity(
        changeAmount, changeTypeEnum, changeComment, traceId);
    final PlatformAccountEntity platformAccount = CommonUtils.requireNotNull(
        platformAccountService.getById(platFormConfig.getId()),
        "系统配置错误,缺失平台信息,请联系管理员");
    platformAccount.setAmount(
            calcChangeAmount(platformAccount.getAmount(), changeTypeEnum.getIoFlag(),
                changeAmount))
        .setStatementAmount(platformAccount.getStatementAmount().add(changeAmount))
    ;
    if (changeTypeEnum.getIoFlag().getCode() < 0) {
      platformAccount.setPayAmount(platformAccount.getPayAmount().add(changeAmount));
    }
    if (moreThanZero(commissionAmount)) {
      platformAccount.setCommissionAmount(
          platformAccount.getCommissionAmount().add(commissionAmount));
    }
    platformAccountDetailService.save(accountDetailEntity);
    platformAccountService.updateById(platformAccount);
  }

  private PlatformAccountDetailEntity initAccountDetailEntity(BigDecimal amount,
      PlatformChangeTypeEnum changeType, String changeComment, String traceId) {
    final Long userId = UserUtil.getUserId();
    final LocalDateTime now = LocalDateTime.now();
    return new PlatformAccountDetailEntity()
        .setPlatformAccountId(platFormConfig.getId())
        .setChangeAmount(amount)
        .setChangeType(changeType.getCode())
        .setChangeTypeName(changeType.getName())
        .setIoFlag(changeType.getIoFlag().getCode())
        .setChangeComment(changeComment)
        .setTraceKey(traceId)
        .setCreateBy(userId)
        .setCreateTime(now)
        .setUpdateBy(userId)
        .setUpdateTime(now);
  }

  private BigDecimal calcChangeAmount(BigDecimal sourceAmount, IOFlagEnum ioFlagEnum,
      BigDecimal changeAmount) {
    if (moreThanZero(changeAmount)) {
      if (ioFlagEnum.getCode() > 0) {
        return sourceAmount.add(changeAmount);
      }
      return sourceAmount.subtract(changeAmount);
    }
    return sourceAmount;
  }

  private boolean moreThanZero(BigDecimal amount) {
    return Optional.ofNullable(amount).orElse(BigDecimal.ZERO).compareTo(BigDecimal.ZERO) > 0;
  }
}
